package cubelabs.nexus.dao;

import java.util.List;
import java.util.StringTokenizer;

import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import cubelabs.nexus.entity.User;

@Repository("userDAO")
public class UserDAO extends BaseDAO<User, Long>{

	
	public User findByEmail(String email){
		Criteria crit = getSession().createCriteria(getPersistentClass());
		crit.add(Restrictions.eq("email", email));
		User user  = (User) crit.uniqueResult();
		return user;
	}

	/*
	 * findExpertLikeName will return experts whose name contains the given name string in the search
	 */
	public List<User> findExpertLikeName(String name){				
		List<User> userList = findByCriteria(
				 Restrictions.and(Restrictions.like("name", name),
								Restrictions.eq("active",true),Restrictions.eq("isExpert",true)));
		return userList;		
	}
	
	/*
	 * findExpertByName will return experts whose name equals the given name string in the search
	 */
	public List<User> findExpertByName(String name){				
		List<User> userList = findByCriteria(
				 Restrictions.and(Restrictions.eq("name", name),
								Restrictions.eq("active",true),Restrictions.eq("isExpert",true)));
		return userList;		
	}
	
        
        public List<User> searchUsers(String categoryString,Integer time, Integer cost,Integer rating,String avaliability, int limit){
            
            String queryStr="SELECT DISTINCT u.* FROM users u, users_category uc, Availability a, category c WHERE u.id=uc.user_id AND uc.category_id = c.id AND a.user_id = u.id AND u.isExpert=1 ";
            String categoryQuery= "";
            
            if(StringUtils.hasLength(categoryString)){
            	categoryQuery="AND (";
            	 StringTokenizer st = new StringTokenizer(categoryString,",");
                 while(st.hasMoreElements()){
                     String category=st.nextToken();
                     categoryQuery+=" c.name LIKE '%"+category+"%' ";
                     if(st.hasMoreElements()){
                         categoryQuery+=" OR ";
                     }else{
                         categoryQuery+=") ";
                     }
                  }
                 queryStr+=categoryQuery;
            }
            
            
            
            
            
            if(cost!=null){
                if(time==2){
                   queryStr+=" AND u.twoMinCost <= "+cost;  
                }else if(time==30){
                     queryStr+=" AND u.thirtyMinCost <= "+cost;
                }else if(time==60){
                     queryStr+=" AND u.oneHourCost <= "+cost;
                }
            }
            
            if(avaliability !=null){
                queryStr+=" AND ("+getAvaliabilityQuery(avaliability)+") "; 
            }
            
            if(rating!=null){
                queryStr+=" AND u.rating >= "+rating;
            }
            
            queryStr += " Limit "+ limit;
            SQLQuery query =  (SQLQuery) getSession().createSQLQuery(queryStr);
            query.addEntity(getPersistentClass());
            List<User> result = query.list();
            return result;
        }

    private String getAvaliabilityQuery(String avaliability) {
        String query =" ";
        String or="";
        if(avaliability.charAt(0)=='1'){
            query +=or+" a.monday is not null ";
            or=" or ";
        }
       if(avaliability.charAt(1)=='1'){
            query +=or+" a.tuesday is not null ";
            or=" or ";
        }       
       if(avaliability.charAt(2)=='1'){
            query +=or+" a.wednesday is not null ";
            or=" or ";
        }
        if(avaliability.charAt(3)=='1'){
            query +=or+" a.thursday is not null ";
            or=" or ";
        }
       if(avaliability.charAt(4)=='1'){
            query +=or+" a.friday is not null ";
            or=" or ";
        }
       if(avaliability.charAt(5)=='1'){
            query +=or+" a.saturday is not null ";
            or=" or ";
        }
       if(avaliability.charAt(6)=='1'){
            query +=or+" a.sunday is not null ";
       }
        return query;
    }
  
}
